#include "room.h"
#include <math.h>

Room::Room(string name) {
    this->name = name;
}

void Room::setCurrentTemperature(double temperature) {
    this->currentTemperature = temperature;
}

void Room::setDesiredTemperature(double temperature) {
    this->desiredTemperature = temperature;
}

/*
 * EN
 * This function adds a wall to the list and calculates the new max power.
 *
 * CZ
 * Tato funkce prida zed do seznamu a vypocte novy max prikon.
 *
 */
void Room::addWall(Wall *wall) {
    this->walls.push_back(wall);
    this->countMaxPower();
}

/*
 * EN
 * This function calculates the radiator maximum power.
 *
 * CZ
 * Tato funkce vypocte maximalni prikon telesa.
 *
 */
void Room::countMaxPower() {
    this->maxPower = 0;
    // projit vsechny zdi
    for (unsigned int i = 0; i < this->walls.size(); i++) {
        // celkovy prikon je dan souctem prikonu zdi
        this->maxPower += this->walls.at(i)->maxPower;
    }
}

/*
 * EN
 * This function sets the desired power and calculates new temperatures.
 * double input      - input radiator power
 *
 * CZ
 * Tato funkce nastavi telesu pozadovany vykon a vypocte nove teploty.
 * double input      - vstupni vykon telesa
 *
 */
void Room::setCurrentPower(double input) {

    this->input = input;

    // aktualni prikon je dan podilem maximalniho prikonu
    this->currentPower = this->input * maxPower;

    // spocitat novou teplotu
    this->countNewTemperature();
}

/*
 * EN
 * This function evaluates the new room temperature using the simple model.
 * Firstly wall temperatures are calculated, the room temperature will be the average.
 *
 * CZ
 * Tato funkce vypocte novou teplotu v pokoji pomoci jednoducheho modelu.
 * Nejprve jsou vypocitany nove teploty zdi, teplota v pokoji jej dana jejich prumerem.
 *
 */
void Room::countNewTemperature() {

    double temperature = 0;
    // projit vsechny zdi
    for (unsigned int i = 0; i < this->walls.size(); i++) {
        Wall *wall = this->walls.at(i);

        // vypocet teploty pro zed
        // vstupem podil vykonu k maximalnimu
        wall->countNewTemperature(this->input);

        // pripocist k promenne pro vypocet prumeru
        temperature += wall->currentTemperature;
    }

    // vypocet prumeru
    temperature /= this->walls.size();

    // nova teplota je prumerem
    this->newTemperature = temperature;
}

/*
 * EN
 * This function sets the desired power and calculates new temperatures.
 * double input      - input radiator power
 *
 * CZ
 * Tato funkce nastavi telesu pozadovany vykon a vypocte nove teploty.
 * double input      - vstupni vykon telesa
 *
 */
void Room::setCurrentPowerComplex(double input) {

    this->input = input;

    // aktualni prikon je dan podilem maximalniho prikonu
    this->currentPower = this->input * maxPower;

    // spocitat novou teplotu
    this->countNewTemperatureComplex();
}

/*
 * EN
 * This function evaluates the new room temperature using the complex model.
 * Firstly wall temperatures are calculated, the room temperature will be the average.
 *
 * CZ
 * Tato funkce vypocte novou teplotu v pokoji pomoci rozsireneho modelu.
 * Nejprve jsou vypocitany nove teploty zdi, teplota v pokoji jej dana jejich prumerem.
 *
 */
void Room::countNewTemperatureComplex() {

    double temperature = 0;
    // projit vsechny zdi
    for (unsigned int i = 0; i < this->walls.size(); i++) {
        Wall *wall = this->walls.at(i);

        // vypocet teploty pro zed
        // vstupem je aktualni vykon deleny poctem zdi
        // kazda zed dostane stejny dil
        wall->countNewTemperatureComplex(this->currentPower/this->walls.size());

        // pripocist k promenne pro vypocet prumeru
        temperature += wall->newTemperature;
    }

    // vypocet prumeru
    temperature /= this->walls.size();

    // nova teplota je prumerem
    this->newTemperature = temperature;
}

/*
 * EN
 * This function updates the current temperature of every wall.
 *
 * CZ
 * Tato funkce pro kazdou zed nahradi aktualni teplotu nove vypoctenou.
 */
void Room::updateTemperatures() {

    // projit vsechny zdi
    for (unsigned int i = 0; i < this->walls.size(); i++) {
        Wall *wall = this->walls.at(i);
        // nahradit starou aktualni teplotu novou
        wall->currentTemperature = wall->newTemperature;
    }
}

